package jhsys.hithink.utils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.util.Log;

public class XmlUtil {
	
	
	

	private  DocumentBuilderFactory factory = null;
	private  DocumentBuilder builder = null;

	/**
	 *example, node string: &lt;a> &lt;b>1&lt;/b> &lt;c>3&lt;/c> &lt;/a>,
	 * return the first node named $nodeName's value
	 * <P>
	 * if namespaceUri is null ,ignore it.
	 * 
	 * @param node
	 * @param namespaceUri
	 * @param nodeName
	 * @return
	 */
	public  String getNodeValue(Node pNode, String namespaceUri,
			String nodeName) {
		return getNodeText(getSingleNode(pNode, namespaceUri, nodeName));
	}

	/**
	 * parse xml from xmlstring
	 * 
	 * @param xmlString
	 * @param useNamespace
	 * @return
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 */
	public  Document parseFromString(String xmlString,
			boolean useNamespace) throws ParserConfigurationException,
			SAXException, IOException, Exception {
		if (xmlString == null || xmlString.trim().length() == 0) {
			throw new Exception("empty xml string.");
		}
		ByteArrayInputStream bais = new ByteArrayInputStream(xmlString
				.getBytes());

		return parse(bais, useNamespace);
	}

	public  Document parse(InputStream is, boolean useNamespace)
			throws ParserConfigurationException, SAXException, IOException {
//		if (factory == null) {
			factory = DocumentBuilderFactory.newInstance();
//		}
		factory.setNamespaceAware(useNamespace);
//		if (builder == null) {
			builder = factory.newDocumentBuilder();
//		}
		Document dom = builder.parse(is);
		return dom;
	}
	
	/**
	 * example, node string: &lt;a>2&lt;/a>,return "2";
	 * 
	 * @param node
	 * @return
	 */
	public  String getNodeText(Node node) {

		String s = null;
		if (node == null) {
			return null;
		}
		Node innerText = node.getFirstChild();
		if (innerText != null && innerText.getNodeType() == Node.TEXT_NODE) {
			s = innerText.getNodeValue();
		}
		// if innerText is null such as <a></a>, return ""
		if (innerText == null) {
			s = "";
		}
		return s;
	}

	/**
	 * example, node string: &lt;a> &lt;b>1&lt;/b> &lt;c>3&lt;/c> &lt;/a>,return
	 * that first node named $nodeName
	 * <P>
	 * if namespaceUri is null ,ignore it.
	 * 
	 * @param parent
	 * @param namespaceUri
	 * @param nodeName
	 * @return
	 */
	public  Node getSingleNode(Node pNode, String namespaceUri,
			String nodeName) {
		if(pNode==null){
			Log.e("XmlUtil", "pNode"+null);
		}
		NodeList nodelist = pNode.getChildNodes();
		for (int i = 0; nodelist != null && i < nodelist.getLength(); i++) {
			Node child = nodelist.item(i);
			
//			Log.e("xmlutil--", "getLocalName:"+child.getLocalName()+"getNodeName:"+child.getNodeName()+"getNamespaceURI:"+child.getNamespaceURI());
			if (namespaceUri != null) {
				// namespace is not null, compare it
				if (namespaceUri.equals(child.getNamespaceURI())
						&& child.getLocalName().equals(nodeName))
					return child;
			} else {
				if (child.getNodeName().equals(nodeName))
					Log.e("XmlUtil", "return child");
					return child;
			}
		}
		return null;
	}

	/**
	 * example, node string: &lt;a> &lt;b>1&lt;/b>
	 * &lt;b>2&lt;/b>&lt;b>3&lt;/b>&lt;/a>,return all nodes named $nodeName;
	 * <P>
	 * if namespaceUri is null ,ignore it.
	 * 
	 * @param pNode
	 * @param namespaceUri
	 * @param nodeName
	 * @return
	 */
	public  List<Node> getNodeList(Node pNode, String namespaceUri,
			String nodeName) {
		NodeList nodelist = pNode.getChildNodes();
		List<Node> nodesNeeds = new ArrayList<Node>();
		for (int i = 0; nodelist != null && i < nodelist.getLength(); i++) {
			Node child = nodelist.item(i);
			if (namespaceUri != null) {
				// namespace is not null, compare it
				if (namespaceUri.equals(child.getNamespaceURI())
						&& child.getLocalName().equals(nodeName)) {
					nodesNeeds.add(child);
				}
			} else {
				if (child.getNodeName().equals(nodeName)) {
					nodesNeeds.add(child);
				}
			}
		}
		return nodesNeeds;
	}

	/**
	 * get first none text node.
	 * 
	 * @param pNode
	 * @return
	 */
	public  Node getFirstNode(Node pNode) {
		Node node = null;
		NodeList nodelist = pNode.getChildNodes();
		for (int i = 0; nodelist != null && i < nodelist.getLength(); i++) {
			Node child = nodelist.item(i);
			if (child.getNodeType() != Node.TEXT_NODE) {
				node = child;
				return node;
			}
		}
		return node;
	}

	/**
	 * example, node string: &lt;a b="1"&gt;&lt;/a&gt;,if $nodeName="b",return
	 * "1";
	 * <P>
	 * if namespaceUri is null ,ignore it.
	 * 
	 * @param node
	 * @param namespaceUri
	 * @param attName
	 * @return
	 */
	public  String getAttributeValue(Node node, String namespaceUri,
			String attName) {
		NamedNodeMap map = node.getAttributes();
		if (namespaceUri == null) {
			return map.getNamedItem(attName) == null ? null : map.getNamedItem(
					attName).getNodeValue();
		} else {
			return map.getNamedItemNS(namespaceUri, attName) == null ? null
					: map.getNamedItemNS(namespaceUri, attName).getNodeValue();
		}
	}
}
